home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 2004 #11
/
Amiga Plus CD - 2004 - No. 11.iso
/
AmiSoft
/
Misc
/
emu
/
fbzx.lha
/
fbzx
/
emulator.c
< prev
next >
Wrap
C/C++ Source or Header
|
2004-08-26
|
6KB
|
280 lines
#include "Z80.h"
#include "computer.h"
#include "emulator.h"
#include "cargador.h"
#include <stdio.h>
#include <stdlib.h>
//#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "characters.h"
#include "menus.h"
#include <string.h>
#include <SDL/SDL.h>
#include <SDL/SDL_thread.h>
#include "sound.h"
#include "tape.h"
#include "microdrive.h"
Z80 procesador;
struct computer ordenador;
SDL_Surface *screen;
char salir;
unsigned char *sound[NUM_SNDBUF];
char path_snaps[2049];
char path_taps[2049];
char path_mdrs[2049];
#ifdef AMIGA
#include <proto/dos.h>
static inline void sleep(unsigned int secs)
{
Delay(secs*50);
}
#endif
void load_rom(char type) {
FILE *fichero;
int size;
switch(type) {
case 0:
// fichero=fopen("/usr/share/spectrum/roms/spectrum.rom","r");
fichero=fopen("roms/spectrum.rom","r");
size=16384;
break;
case 1:
// fichero=fopen("/usr/share/spectrum/roms/128.rom","r");
fichero=fopen("roms/128.rom","r");
size=32768;
break;
case 2:
// fichero=fopen("/usr/share/spectrum/roms/plus2.rom","r");
fichero=fopen("roms/plus2.rom","r");
size=32768;
break;
case 3:
// fichero=fopen("/usr/share/spectrum/roms/plus3.rom","r");
fichero=fopen("roms/plus3.rom","r");
size=65536;
break;
default:
fichero=NULL;
size=0;
}
if(fichero==NULL) {
printf("Can't open ROM file\n");
exit(1);
}
fread(ordenador.memoria,size,1,fichero);
fclose(fichero);
// fichero=fopen("/usr/share/spectrum/roms/if1-v2.rom","r"); // load Interface1 ROM
fichero=fopen("roms/if1-v2.rom","r"); // load Interface1 ROM
if(fichero==NULL) {
printf("Can't open Interface1 ROM file\n");
exit(1);
}
fread(ordenador.shadowrom,8192,1,fichero);
fclose(fichero);
}
void init_screen(int resx,int resy,int depth) {
int retorno,bucle,bucle2;
retorno=SDL_Init(SDL_INIT_VIDEO);
if(retorno!=0) {
printf("Can't initialize SDL library. Exiting\n");
exit(1);
}
// screen initialization
screen=SDL_SetVideoMode(resx,resy,depth,SDL_HWSURFACE|SDL_HWPALETTE);
if(screen==NULL) {
printf("Can't assign SDL Surface. Exiting\n");
exit(1);
}
if(SDL_MUSTLOCK(screen)) {
ordenador.mustlock=1;
SDL_LockSurface(screen);
} else
ordenador.mustlock=0;
// sound initialization
if(sound_init(48000,2048)!=0) {
printf("Can't initialize sound. Exiting. (Try with 'nosound')\n");
exit(1);
}
for(bucle2=0;bucle2<NUM_SNDBUF;bucle2++) {
sound[bucle2]=(unsigned char *)malloc(ordenador.buffer_len+4);
for(bucle=0;bucle<ordenador.buffer_len;bucle++)
sound[bucle2][bucle]=0;
}
if(ordenador.format)
ordenador.increment=2*ordenador.channels;
else
ordenador.increment=ordenador.channels;
ordenador.tst_sample=3500000/ordenador.freq;
set_volume(70);
}
void end_system() {
sound_close();
if(ordenador.mustlock)
SDL_UnlockSurface(screen);
if(ordenador.tap_file!=NULL)
fclose(ordenador.tap_file);
SDL_Quit();
}
int main(int argc,char *argv[]) {
int bucle,tstados;
word PC;
sound_type=0;
if(argc==2)
if(0==strcmp(argv[1],"nosound"))
sound_type=1;
atexit(end_system);
init_screen(640,480,8);
computer_init();
register_screen(screen);
ordenador.interr=0;
ordenador.screenbuffer=ordenador.screen->pixels;
ordenador.screen_width=ordenador.screen->w;
// assign initial values for PATH variables
strcpy(path_snaps,getenv("HOME"));
strcat(path_snaps,"/");
strcpy(path_taps,path_snaps);
strcpy(path_mdrs,path_snaps);
ordenador.current_tap[0]=0;
// assign random values to the memory before start execution
for(bucle=0;bucle<196608;bucle++)
ordenador.memoria[bucle]=(unsigned char) rand();
ordenador.tap_file=NULL;
// we filter all the events, except keyboard events
SDL_EventState(SDL_ACTIVEEVENT,SDL_IGNORE);
SDL_EventState(SDL_MOUSEMOTION,SDL_IGNORE);
SDL_EventState(SDL_MOUSEBUTTONDOWN,SDL_IGNORE);
SDL_EventState(SDL_MOUSEBUTTONUP,SDL_IGNORE);
SDL_EventState(SDL_JOYAXISMOTION,SDL_IGNORE);
SDL_EventState(SDL_JOYBALLMOTION,SDL_IGNORE);
SDL_EventState(SDL_JOYHATMOTION,SDL_IGNORE);
SDL_EventState(SDL_JOYBUTTONDOWN,SDL_IGNORE);
SDL_EventState(SDL_JOYBUTTONUP,SDL_IGNORE);
SDL_EventState(SDL_QUIT,SDL_IGNORE);
SDL_EventState(SDL_SYSWMEVENT,SDL_IGNORE);
SDL_EventState(SDL_VIDEORESIZE,SDL_IGNORE);
SDL_EventState(SDL_USEREVENT,SDL_IGNORE);
SDL_ShowCursor(SDL_DISABLE);
salir=1;
ResetComputer();
procesador.Trace=0;
procesador.IAutoReset=0;
procesador.TrapBadOps=0;
procesador.ICount=200; // to ensure that all operations will be done
procesador.TStates=0;
sleep(1);
clean_screen();
microdrive_init();
while(salir) {
PC=ExecZ80(&procesador);
/* if PC is 0x0556, a call to LD_BYTES has been made, so if
FAST_LOAD is 1, we must load the block in memory and return */
if((!ordenador.mdr_paged)&&(PC==0x0556) && (ordenador.tape_fast_load==1)&&(ordenador.tape_file_type==TAP_TAP)) {
if(ordenador.tap_file!=NULL)
fastload_block(ordenador.tap_file);
else {
sprintf(ordenador.osd_text,"No TAP file selected");
ordenador.osd_time=50;
}
}
/* if PC is 0x04C2, a call to SA_BYTES has been made, so if
we want to save to the TAP file, we do it */
if((!ordenador.mdr_paged)&&(PC==0x04C2)&&(ordenador.tape_write==1)&&(ordenador.tape_file_type==TAP_TAP)) {
if(ordenador.tap_file!=NULL)
save_file(ordenador.tap_file);
else {
sprintf(ordenador.osd_text,"No TAP file selected");
ordenador.osd_time=50;
}
}
/* if ordenador.mdr_paged is 2, we have executed the RET at 0x0700, so
we have to return to the classic ROM */
if(ordenador.mdr_paged==2)
ordenador.mdr_paged=0;
/* if PC is 0x0008 or 0x1708, and we have a microdrive, we have to page
the Interface 1 ROM */
if(((PC==0x0008)||(PC==0x1708))&&(ordenador.mdr_active))
ordenador.mdr_paged = 1;
/* if PC is 0x0700 and we have a microdrive, we have to unpage
the Interface 1 ROM after the last instruction */
if((PC==0x0700)&&(ordenador.mdr_active))
ordenador.mdr_paged = 2;
tstados=procesador.TStates;
if(tstados==0)
tstados=4; // if we are in halt, we execute virtual NOPs
if(tstados<0) {
printf("Error\n");
exit(1);
}
emulate(tstados); // execute the whole hardware emulation
procesador.ICount=200; // to ensure that all operations will be done
procesador.TStates=0;
if(ordenador.interr==1) {
IntZ80(&procesador,bus_empty()); // execute the interruption
ordenador.interr=0;
}
}
return 0;
}